package dao;

import dao.inte.UserRepository;
import domain.User;
import org.springframework.transaction.annotation.Transactional;

import javax.inject.Singleton;
import javax.persistence.NoResultException;
import javax.persistence.NonUniqueResultException;
import javax.persistence.Query;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Path;
import javax.persistence.criteria.Root;
import java.util.List;
import java.util.logging.Logger;

@Singleton
@Transactional
public class UserRepositoryImpl extends AbstractEntityRepository<User> implements UserRepository {
    public UserRepositoryImpl() {
        super(User.class);
    }

    private final static Logger logger = Logger.getLogger(UserRepositoryImpl.class.getName());


    @Override
    protected Class<User> getEntityClass() {
        return User.class;
    }

    @Transactional(noRollbackFor = NoResultException.class)

    public User findByLogin(String login) throws NonUniqueResultException {
        Query q = entityManager.createQuery("from User u where u.login = :login");
        q.setParameter("login", login);
        User user = null;


        try {
            user = (User) q.getSingleResult();
        } catch (NoResultException e) {
            //OK
        }
        return user;
    }

    public User findByMail(String companyEmail) {
        Query q = entityManager.createQuery("from User u where u.company.companyEmail = :companyEmail");
        q.setParameter("companyEmail", companyEmail);
        return (User) q.getSingleResult();
    }

    public List<User> findUsers(int first, int count, String property, boolean ascending) {
        CriteriaBuilder cb = entityManager.getCriteriaBuilder();
        CriteriaQuery cq = cb.createQuery(User.class);
        Root personEntity = cq.from(User.class);
        Path attr;
        if (property.equals("id")) {
            attr = personEntity.get("id");
        } else if (property.equals("lastName")) {
            attr = personEntity.get("lastName");

        } else if (property.equals("firstName")) {
            attr = personEntity.get("firstName");

        } else if (property.equals("mail")) {
            attr = personEntity.join("company").get("companyEmail");
        } else {
            attr = personEntity.get("login");
        }
        if (ascending) {
            cq.orderBy(cb.asc(attr));
        } else {
            cq.orderBy(cb.desc(attr));
        }
        TypedQuery<User> query = entityManager.createQuery(cq);
        query.setFirstResult(first);
        query.setMaxResults(count);
        List<User> results = query.getResultList();
        return results;
    }
}
